/**
 * @file pdf.c 
 gcc -Wall -g pdf.c -lm -lhpdf  && ./a.out "/home/libiao/Desktop/11331842w.pdf" "/home/libiao/.appdata/com.huaien.jiapu2/Local Store/11331842/w/"
 gcc -Wall -g *.c -lm  && ./a.out "/home/libiao/Desktop/11331842w.pdf" "/home/libiao/.appdata/com.huaien.jiapu2/Local Store/11331842/w/"
 ./a.out ~/test.pdf "$HOME/.appdata/com.huaien.jiapu2/Local Store/100004" && sh -c "xdg-open ~/test.pdf &"
 gcc -Wall -g pdf.c -lm -lhpdf && ./a.out ~/test.pdf "$HOME/.appdata/com.huaien.jiapu2/Local Store/100004" && sh -c "xdg-open ~/test.pdf &"
 gcc -Wall -g pdf.c -lm -lhpdf && ./a.out ~/test.pdf "$HOME/.appdata/com.huaien.jiapu2/Local Store/11388116/h" && sh -c "xdg-open ~/test.pdf &"
 gcc -Wall -g pdf.c -D __HAS_FREETYPE__  -I"/usr/include/freetype2/"  -D __DEBUG__ -lfreetype -lm -lhpdf && ./a.out ~/test.pdf "$HOME/.appdata/com.huaien.jiapu2/Local Store/11388580/w" && sh -c "xdg-open ~/test.pdf &"

 gcc -g pdf.c -D __DEBUG__ -lm -lhpdf && ./a.out ~/test.pdf "$HOME/.appdata/com.huaien.jiapu2/Local Store/11351573/s" && sh -c "xdg-open ~/test.pdf &"
 gcc -g pdf.c -D __DEBUG__ -lm -lhpdf && ./a.out ~/test.pdf "$HOME/.appdata/com.huaien.jiapu2/Local Store/11335602/s" && sh -c "xdg-open ~/test.pdf &"
 gcc -g pdf.c -D __DEBUG__ -I"/usr/include/freetype2/"  -lm -lhpdf && ./a.out ~/test.pdf "$HOME/.appdata/com.huaien.jiapu2/Local Store/11335602/s" && sh -c "xdg-open ~/test.pdf &"
 gcc -g pdf.c -D __DEBUG__ -D __HAS_FREETYPE__ -lfreetype -I"/usr/include/freetype2/"  -lm -lhpdf && ./pdf "$HOME/.appdata/com.huaien.jiapu2/Local Store/11382556" New x s w
 gcc -g pdf.c -D __DEBUG__ -D __HAS_FREETYPE__ -lfreetype -I"/usr/include/freetype2/"  -lm -lhpdf && ./a.out ~/test.pdf "/home/libiao/.appdata/com.huaien.jiapu2/Local Store/11361308/x" && sh -c "xdg-open ~/test.pdf &"
 gcc -g pdf.c -D __DEBUG__ -D __HAS_FREETYPE__ -lfreetype -I"/usr/include/freetype2/"  -lm -lhpdf && ./a.out ~/test.pdf "/home/libiao/.appdata/com.huaien.jiapu2/Local Store/11377133/w" && sh -c "xdg-open ~/test.pdf &"
 gcc -g pdf.c -D __DEBUG__ -D __HAS_FREETYPE__ -lfreetype -I"/usr/include/freetype2/"  -lm -lhpdf && ./a.out ~/test.pdf "/home/libiao/.appdata/com.huaien.jiapu2/Local Store/11360632/w" && sh -c "xdg-open ~/test.pdf &"
 gcc -lm *.c
 gcc pdf.c -L"." "libhpdf.lib" -lpng14 "zlib.lib" -I"include" 

 a.exe 导出pdf文件名 配置文件夹名(+页码数字+".txt"为本地路径) 起始页(123...) 总页数
// 不能嵌入的字体: font/FZDBSJW--GB1-0.ttf(no use any more), font/FZDBSFW--GB1-0.ttf, font/FZXKJW--GB1-0.ttf, 必须安装字体


HPDF_Page_SetSize
1
HPDF_PAGE_SIZE_LETTER
8½ x 11 (Inches)	612 x 792
2
HPDF_PAGE_SIZE_LEGAL
8½ x 14 (Inches)	612 x 1008
3
HPDF_PAGE_SIZE_A3
297 × 420 (mm)
841.89 x 1199.551
4
HPDF_PAGE_SIZE_A4
210 × 297 (mm)
595.276 x 841.89
5
HPDF_PAGE_SIZE_A5
148 × 210 (mm)	419.528 x 595.276
6
HPDF_PAGE_SIZE_B4
250 × 353 (mm)	708.661 x 1000.63
7
HPDF_PAGE_SIZE_B5
176 × 250 (mm)	498.898 x 708.661
8
HPDF_PAGE_SIZE_EXECUTIVE
7½ x 10½ (Inches)
522 x 756
9
HPDF_PAGE_SIZE_US4x6
4 x 6 (Inches)
288 x 432
10
HPDF_PAGE_SIZE_US4x8
4 x 8 (Inches)
288 x 576
11
HPDF_PAGE_SIZE_US5x7
5 x 7 (Inches)
360 x 504
12
HPDF_PAGE_SIZE_COMM10
4.125 x 9.5 (Inches)	297x 684



 * @author db0@qq.com
 * @version 1.0.1
 * @date 2017-04-07
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <setjmp.h>
#include <unistd.h>
#include <iconv.h>
#include "hpdf.h"

#include "time.h"
#include <dirent.h>
#include <sys/stat.h>

#ifdef __HAS_FREETYPE__
#include <ft2build.h>
#include FT_FREETYPE_H // for freetype support
#include FT_GLYPH_H
#endif

//HPDF_EXPORT(HPDF_STATUS)
//HPDF_STATUS HPDF_UseUTFEncodings   (HPDF_Doc   pdf);

jmp_buf env;
HPDF_Doc  pdf;



char * fonts[] = {
	"SimSun",//宋体
	"CloudSongDaGBK",
	"FZXKJW--GB1-0",//can not embed
	"FZDBSFW--GB1-0",//can not embed
	"FZXKFW--GB1-0",
	"STLiti",//华文隶书
	"Tensentype BoDangXingKaiF",//腾祥伯当行楷繁
	"STXingkai_GBK",//华文行楷
	"HYf1gj",//汉仪大隶书简
	"HYf1gf",//
	"HYc1gf",//汉仪楷体繁
	"STXinwei",
	"HYd1gj",//汉仪仿宋简
	"HYd1gf",//HYFangSongJ
	"FZKTK--GBK1-0",
	NULL
};


#ifdef HPDF_DLL
void  __stdcall
#else
void
#endif
error_handler  (HPDF_STATUS   error_no,
		HPDF_STATUS   detail_no,
		void         *user_data)
{
	printf ("ERROR: error_no=%04X, detail_no=%u\n", (HPDF_UINT)error_no,
			(HPDF_UINT)detail_no);
#ifdef __DEBUG__
	switch(error_no)
	{
		case HPDF_TTF_CANNOT_EMBEDDING_FONT:
			printf("HPDF_TTF_CANNOT_EMBEDDING_FONT\r\n");
			return;
			break;
		case HPDF_INVALID_TTC_FILE:
			printf("HPDF_INVALID_TTC_FILE\r\n");
			break;
		case HPDF_TTF_INVALID_CMAP:
			printf("HPDF_TTF_INVALID_CMAP\r\n");
			break;
		case HPDF_TTF_INVALID_FOMAT:
			printf("HPDF_TTF_INVALID_FOMAT\r\n");
			break;
		case HPDF_INVALID_DOCUMENT:
			printf("HPDF_INVALID_DOCUMENT\r\n");
			break;
	}
#endif
	longjmp(env, 1);
}

int fileExists(char * path)
{
	/**
	  06     检查读写权限
	  04     检查读权限
	  02     检查写权限
	  01     检查执行权限
	  00     检查文件的存在性
	  */
	if(path==NULL || strlen(path)==0)
		return 0;
	int i = access(path,0);
	return (i!=-1);
}

int compareString(const void *a, const void *b) {
	char *s1 = *(char**)a;
	char *s2 = *(char**)b;
	return atoi(s1) - atoi(s2);
}

char ** getFilesInDirectory(const char * dirPath,char *suffix,int minIndex,int * numFiles) 
{ 
	char ** list = NULL;
	int nFiles = 0;
	char ** fileList = NULL;
	DIR              *pDir ; 
	struct dirent    *ent  ; 
	struct stat sb; 

	if(numFiles && *numFiles<=0)
		*numFiles = 0xfffff;

	pDir=opendir(dirPath); 
	//printf("opendir: %s,%s\n",dirPath,pDir);
	while((ent=readdir(pDir))!=NULL) 
	{ 
		char * fname = ent->d_name;
		if(strlen(fname)==0)
			continue;
		int flen = strlen(dirPath)+strlen(fname) + 2;
		char curFile[flen];
		memset(curFile,0,flen);
		sprintf(curFile,"%s/%s",dirPath,fname);
		int willPush=0;
		if(*fname=='.') {
		}else if(stat(curFile, &sb) >= 0 && S_ISDIR(sb.st_mode)) { //directory
		} else if(suffix){
			char *fileSuffix = strrchr(ent->d_name,'.');
			if(strcmp(fileSuffix,suffix)==0){
				willPush = 1;
			}
		}else{
			willPush = 1;
		}
		if(willPush && strlen(fname)>0){
			int pathLen = strlen(fname)+1;
			char * filename = malloc(pathLen);
			memset(filename,0,pathLen);
			sprintf(filename,"%s",fname);
			if(fileList==NULL){
				fileList = (char**)malloc(sizeof(char*));
			}else{
				fileList = (char**)realloc(fileList,sizeof(char*)*(nFiles+1));
			}
			fileList[nFiles++] = filename;
			//printf("%s\n",filename);
		}else{
			//printf("Other file: %s\n",curFile);
		}
	}
	printf("nFiles: %d\n",nFiles);
	qsort(fileList, nFiles, sizeof(char*), compareString);
	int i = 0;
	int num = 0;
	while(i< nFiles)
	{
		char * filename = fileList[i];
		if(filename==NULL)
		{
			++i;
			continue;
		}
		int index = atoi(filename);
		//printf("%d\n",index);
		if(index>=minIndex && num<*numFiles){
			int pathLen = strlen(dirPath)+strlen(filename)+2;
			char * fullPath = malloc(pathLen);
			memset(fullPath,0,pathLen);
			sprintf(fullPath,"%s/%s",dirPath,filename);
			if(list==NULL){
				list = (char**)malloc((num+1)*sizeof(char*));
			}else{
				list = (char**)realloc(list,(num+1)*sizeof(char*));
			}
			//printf("filename: %s\n",filename);
			//printf("fullPath: %s\n",fullPath);
			list[num++] = fullPath;
		}
		free(filename);
		fileList[i]=NULL;
		i++;
	}
	if(numFiles)
	{
		(*numFiles) = num;
	}
	//printf("numFiles: %d\n",*numFiles);
	closedir(pDir);
	if(fileList) free(fileList);
	return list;
} 


typedef struct MyFont{
	char * name;
	char * path;
	HPDF_Font font;
#ifdef __HAS_FREETYPE__
	FT_Face * face;
#endif
}MyFont;
MyFont allFonts[128];
int numFonts=0;

MyFont * embedFont(char * name,HPDF_BOOL b)
{
	if(
			strcmp("FZDBSJW--GB1-0",name)==0
			|| strcmp("FZDBSFW--GB1-0",name)==0
			|| strcmp("FZXKJW--GB1-0",name)==0
	  ){//font cannot embed
		b = HPDF_FALSE;
	}

	int len = strlen(name)+11;
	char * path = malloc(len);
	memset(path,0,len);
	sprintf(path,"font/%s.ttf",name);
	if(path && fileExists(path)){
#ifdef WIN32
		if(b==HPDF_FALSE)
		{
			char wpath[len+16];
			memset(wpath,0,sizeof(wpath));
			sprintf(wpath,"c:/Windows/Fonts/%s.ttf",name);
			if(!fileExists(wpath)){
				char cmd[len+32];
				memset(cmd,0,sizeof(cmd));
				sprintf(cmd,"FontReg.exe /copy font/%s.ttf",name);
				printf("%s\n",cmd);
				//system(cmd);
			}
		}
#endif
		MyFont * myfont = &(allFonts[numFonts]);
		myfont->path = path;
		len = strlen(name)+1;
		char * _name = malloc(len);		
		memset(_name,0,len);
		sprintf(_name,"%s",name);
		myfont->name = (char*)HPDF_LoadTTFontFromFile(pdf, path, b);
		//myfont->name = _name;
		myfont->font = HPDF_GetFont(pdf,myfont->name,"GBK-EUC-H");///SimSun宋体、SimHei黑体 
		//myfont->font = HPDF_GetFont(pdf,myfont->name,"GB18030-EUC-H");///SimSun宋体、SimHei黑体 
#ifdef __HAS_FREETYPE__
		myfont->face = NULL;
#endif
		printf("fontPath: %s,fontName: %s\r\n",myfont->path,myfont->name);
		if(strcmp(myfont->name,name)){
			exit(1);
		}
		numFonts++;
		return myfont;
	}else{
		printf("fontPath: %s not exists\r\n",path);
	}
	return NULL;
}

MyFont * getFontByName(char * name)
{
#ifdef __DEBUG__
	if(strcmp("FZXKJW--GB1-0",name)==0){
		name = "STXingkai_GBK";
	}else if( strcmp("FZDBSJW--GB1-0",name)==0){
		name = "CloudSongDaGBK";//锐字云字库大标宋体
	}else if( strcmp("FZDBSFW--GB1-0",name)==0){
		name = "HYf1gj";
		name = "HYf1gf";
		name = "HYc1gf";
		name = "HYd1gf";
		name = "Tensentype BoDangXingKaiF";
		name = "STLiti";
		name = "HYd1gj";
		name = "FZXKFW--GB1-0";

		name = "Reeji-CloudXingCao-GB-Regular";//锐字云字库行草GB

		name = "STXinwei";//华文新魏
		name = "Reeji-CloudLiSu-GBK";//锐字工房云字库隶书GBK
		name = "CloudLiBianGBK";//锐字云字库隶变体
		//name = "ShanghaiFace-Zen-ExtraBoldGB2.0,Zen-ExtraBoldGB2.0";//海派腔调禅大黑简2.0
		name = "CloudRuiSongCuGBK";//锐字云字库锐宋粗体GBK
		name = "STZhongsong";//长城特粗宋体
		name = "FZCSFW--GB1-0";

		name = "CloudLiBianGBK";
		name = "Reeji-CloudLiSu-GBK";//锐字工房云字库隶书GBK
		name = "FZDBSK--GBK1-0";//
		name = "CloudSongDaGBK";//锐字云字库大标宋体
	}
	//name = "HYf2gjgb18030sp";//汉仪小隶书
	//name = "FZKTK--GBK1-0";//方正楷体_GBK
#endif

	int i = 0;
	MyFont * font = NULL; 
	while(i<numFonts)
	{
		MyFont * myfont = &(allFonts[i]);
		if(strcmp(myfont->name,name)==0){
			font = myfont;
			break;
		}
		++i;
	}
	if(font==NULL)
		return embedFont(name,HPDF_TRUE);
	return font;
}


MyFont * _defaultFont;
MyFont * getDefaultFont()
{
	if(_defaultFont==NULL){
		_defaultFont = getFontByName("SimSun");
	}
	if(_defaultFont==NULL)
	{
		_defaultFont = &allFonts[numFonts];
		_defaultFont->name = "SimSun";
		_defaultFont->font = HPDF_GetFont(pdf,"SimSun","GBK-EUC-H");///SimSun宋体、SimHei黑体 
		//_defaultFont->font = HPDF_GetFont(pdf,"SimSun","GB18030-EUC-H");///SimSun宋体、SimHei黑体 
		_defaultFont->path = NULL;
#ifdef __HAS_FREETYPE__
		_defaultFont->face = NULL;
#endif
		numFonts++;
	}
	return _defaultFont;
}
void draw_line(HPDF_Page page,int x1,int y1,int x2,int y2,int size,unsigned int color)
{
	//int pageW = HPDF_Page_GetWidth(page);
	int pageH = HPDF_Page_GetHeight(page);
	float r = (float)((color>>16)&0xff)/0xff;
	float g = (float)((color>>8)&0xff)/0xff;
	float b = (float)((color)&0xff)/0xff;
	HPDF_Page_SetRGBStroke (page, r, g, b);
	HPDF_Page_SetLineWidth (page, size);
	HPDF_Page_MoveTo (page, x1, pageH-y1);
	HPDF_Page_LineTo (page, x2, pageH-y2);
	HPDF_Page_Stroke (page);
}
void draw_rect(HPDF_Page page,int x,int y,int w,int h,int size,unsigned int color,unsigned bgcolor)
{
	//int pageW = HPDF_Page_GetWidth(page);
	int pageH = HPDF_Page_GetHeight(page);
	HPDF_Page_SetLineWidth (page, size);
	float r = (float)((color>>16)&0xff)/0xff;
	float g = (float)((color>>8)&0xff)/0xff;
	float b = (float)((color)&0xff)/0xff;
	HPDF_Page_SetRGBStroke (page, r, g, b);
	HPDF_Page_Rectangle (page, x, pageH-y-h, w, h);
	HPDF_Page_Stroke (page);
}

void draw_image(HPDF_Page page,HPDF_Image hpdfImage,int x,int y,int w,int h)
{
	int pageH = HPDF_Page_GetHeight(page);
	HPDF_Page_DrawImage(page, hpdfImage, x, pageH-y-h, w, h);
}


void draw_image_file(HPDF_Page page,char * url,int x,int y,int w,int h)
{
	if(strncasecmp(url,"http:",5)==0)
		return;
	int exists = fileExists(url);
	if(!exists)
	{
		printf("%s not exists!\n",url);
		return;
	}
	HPDF_Image hpdfImage=NULL;
	hpdfImage = HPDF_LoadJpegImageFromFile(pdf, url);
	if(0 && hpdfImage==NULL){
		int len = strlen(url);
		if(strcasecmp(".png",url+(len-4))==0){
			hpdfImage = HPDF_LoadPngImageFromFile2(pdf, url);
		}
	}

	//printf("%s exists!\n",url);
	if (hpdfImage==NULL){
		printf("%s 2 not exists!\n",url);
		return;
	}
	int pageH = HPDF_Page_GetHeight(page);
	HPDF_Page_DrawImage(page, hpdfImage, x, pageH-y-h, w, h);
	return;
	//int pageW = HPDF_Page_GetWidth(page);

	int pW = HPDF_Image_GetWidth(hpdfImage);
	int pH = HPDF_Image_GetHeight(hpdfImage);
	float scaleX = (float)pW/w;
	float scaleY = (float)pH/h;
	float scale = scaleX<scaleY?scaleX:scaleY;
	int ww = pW*scale;
	int hh = pH*scale;
	int xx = x;
	int yy = y;
	if(scaleX<scaleY){
		xx = (w-ww)/2;
	}else{
		yy = (h-ww)/2;
	}
	HPDF_Page_DrawImage(page, hpdfImage, xx, pageH-yy-hh, ww, hh);
}

char * UTF8_encodeTo(char* inbuf,size_t * outlen,char * coding){
	size_t inlen =strlen(inbuf);
	iconv_t cd=iconv_open(coding,"UTF-8");
	char*outbuf=(char*)malloc(inlen*4);
	memset(outbuf,0,inlen*4);
	char*in=inbuf;
	char*out=outbuf;
	*outlen=inlen*4;
#ifdef WIN32
	iconv(cd,(const char **)&in,(size_t*)&inlen,&out,outlen);
#else
	iconv(cd,(char **)&in,(size_t*)&inlen,&out,outlen);
#endif
	*outlen=strlen(outbuf);
	//printf("%s\n",outbuf);
	//free(outbuf);
	iconv_close(cd);
	return outbuf;
}

#ifdef __HAS_FREETYPE__
FT_Library * library;
#endif
int hasGlyphs(MyFont * myfont,char * s)
{
#ifdef __HAS_FREETYPE__
	if(myfont==NULL)
		return 0;
	if(myfont->face==NULL)
	{
		if(library==NULL)
		{
			library = malloc(sizeof(FT_Library));
			memset(library,0,sizeof(FT_Library));
		}
		FT_Error error = FT_Init_FreeType( library );
		if( error ) {
			printf( " initial freetype failed.\n" );
			free(library);
			library = NULL;
			return 0;
		}
		myfont->face = malloc(sizeof(FT_Face));
		memset(myfont->face,0,sizeof(FT_Face));
		error = FT_New_Face(*library, myfont->path, 0, myfont->face );
		if( error == FT_Err_Unknown_File_Format ) {
			printf( " unknown font format.\n" );
			return 0;
		} else if( error ){
			printf( " error to load font.\n" );
			return 0;
		}
	}
	size_t outlen;
	char * t = UTF8_encodeTo(s,&outlen,"UTF-16");
	int num_chars = outlen/2;
	int n;
	for (n = 0; n < num_chars; n++ ) {
#ifdef WIN32
		unsigned short k = (t[2*n+1]&0xff)+((t[2*n]&0xff)<<8);
#else
		unsigned short k = (t[2*n]&0xff)+((t[2*n+1]&0xff)<<8);
#endif
		if(k==0xfeff || k==0 ||k==0xfffe)
			continue;
		int glyph_index = FT_Get_Char_Index(*(myfont->face),k);
		if(glyph_index<=0){
			return 0;
		}
	}
	free(t);
	return 1;
	/*
	   FT_Done_Face( *(myfont->face) );
	   myfont->face = NULL;
	   FT_Done_FreeType( *library );
	   library=NULL;
	   return 1;
	   */
#endif
	return 1;
}


void draw_font(HPDF_Page page,char * s,int x,int y,int size)
{
	printf("\ndraw_font: %s\n",s);
	size_t outlen;
	char *s2 = UTF8_encodeTo(s,&outlen,"Unicode");
	char url[16];
	memset(url,0,sizeof(url));
	printf("%2x%2x",s2[1]&0xff,s2[0]&0xff);
	if((unsigned char)s2[0]==0xff && (unsigned char)s2[1]==0xfe)
		sprintf(url,"font/%2x%2x.png",s2[3]&0xff,s2[2]&0xff);
	else
		sprintf(url,"font/%2x%2x.png",s2[1]&0xff,s2[0]&0xff);
	free(s2);
	if(fileExists(url)){
		draw_image_file(page,url,x-size/2,y,size,size);
	}
}

void draw_text(HPDF_Page page,MyFont * myfont,char *s,int x,int y,int w,int h,int size,unsigned int color,int isV)
{
	if(size<=0)
		return;
	size_t outlen;
	char *s2 = UTF8_encodeTo(s,&outlen,"GBK");
	if(myfont!=getDefaultFont()){
		if(hasGlyphs(myfont,s)==0){
#ifndef WIN32
			printf("%s:%s\n",s,myfont->name);
#endif
			myfont = getDefaultFont();
		}
	}
	if(isV && strcmp(s,"…")==0){
		x += size/2;
		y -= size*.8;
		myfont->font = HPDF_GetFont(pdf,myfont->name,"GBK-EUC-V");
	}else{
		myfont->font = HPDF_GetFont(pdf,myfont->name,"GBK-EUC-H");
	}
	//int pageW = HPDF_Page_GetWidth(page);
	int pageH = HPDF_Page_GetHeight(page);
	HPDF_Page_BeginText (page);
	HPDF_Page_SetFontAndSize (page, myfont->font, size);

	float r = (float)((color>>16)&0xff)/0xff;
	float g = (float)((color>>8)&0xff)/0xff;
	float b = (float)((color)&0xff)/0xff;
	static int bold=0;
#ifdef __DEBUG__
	//bold++; if(bold>3) bold = -2;
#endif
	if(bold>0)
	{
		HPDF_Page_SetLineWidth(page,(float)size/100);
		HPDF_Page_SetTextRenderingMode (page, HPDF_FILL_THEN_STROKE);
	}else{
		HPDF_Page_SetTextRenderingMode (page, HPDF_FILL);
	}
	HPDF_Page_SetRGBFill (page, r, g, b);
	//HPDF_Page_MoveTextPos (page, x, pageH-y);
	//HPDF_Page_ShowText (page, s);

	HPDF_UINT len;
	//HPDF_Page_TextOut (page, x, pageH-y-size, s2);
	HPDF_Page_TextRect (page,x,pageH-y, x+w, y-h, s2, HPDF_TALIGN_LEFT, &len);
	//HPDF_Page_TextRect (page,x,pageH-y, x+w, y-h, s2, HPDF_TALIGN_JUSTIFY, NULL);
	if(len==0){
		//HPDF_TextWidth txtw = HPDF_Font_TextWidth(myfont->font,s2,outlen);
		//printf("\n numchars:%d,numwords:%d,width:%d,numspace:%d",txtw.numchars,txtw.numwords,txtw.width,txtw.numspace);
		//HPDF_Page_TextRect (page,x,pageH-y, x+txtw.width/100, y-h, s2, HPDF_TALIGN_LEFT, &len);
		HPDF_Page_TextOut (page, x, pageH-y-size, s2);
		//draw_font(page,s,x,y,size);
	}
	HPDF_Page_EndText (page);

	free(s2);
}

size_t fileSize(FILE*stream)
{
	size_t curpos,length;
	curpos=ftell(stream);
	fseek(stream,0L,SEEK_END);
	length=ftell(stream);
	fseek(stream,curpos,SEEK_SET);
	return length;
}

char * readfile(char * path,size_t * _filesize)
{
	if(_filesize)*_filesize = 0;
	if(path==NULL)
		return NULL;
	char * _path = path;
	FILE * file = fopen(_path,"rb");	
	free(_path);
	if(file==NULL)
		return NULL;
	size_t filesize = 0;
	filesize = fileSize(file);
	char *buffer = (char*)malloc(filesize+1);
	if(buffer)
	{
		memset(buffer,0,filesize+1);
		rewind(file);
		int ret=fread(buffer,1,filesize,file);
		if(ret!=filesize){
			free(buffer);
			buffer = NULL;
			filesize = 0;
		}
	}
	fclose(file);
	if(_filesize)*_filesize = filesize;
	return buffer;
}

void embedFonts()
{
	numFonts = 0;
	memset(allFonts,0,sizeof(allFonts));
	printf("embedFonts\n");
	embedFont("SimSun",HPDF_TRUE);//宋体

	/*
	   embedFont("FZDBSJW--GB1-0",HPDF_FALSE);//方正大标宋简体
	   embedFont("FZDBSFW--GB1-0",HPDF_FALSE);//方正大标宋繁体
	   embedFont("FZXKJW--GB1-0",HPDF_FALSE);//方正行楷简体

	   embedFont("FZXKFW--GB1-0",HPDF_TRUE);//方正行楷繁体
	   embedFont("STLiti",HPDF_TRUE);//华文隶书
	   embedFont("Tensentype BoDangXingKaiF",HPDF_TRUE);//腾祥伯当行楷繁
	   embedFont("STXingkai_GBK",HPDF_TRUE);//华文行楷
	   embedFont("HYf1gj",HPDF_TRUE);//汉仪大隶书简
	   embedFont("HYf1gf",HPDF_TRUE);//汉仪大隶书繁
	   embedFont("HYc1gf",HPDF_TRUE);//汉仪楷体繁
	   embedFont("HYd1gf",HPDF_TRUE);//汉仪仿宋繁
	   embedFont("HYd1gj",HPDF_TRUE);//汉仪仿宋简
	   */
}

void parseTxt(HPDF_Page page,char * l)
{
	if(l==NULL || strlen(l)<10)
		return;
	//printf("%s\r\n",l);
	//return;
	int isV = 0;
	if(l[1]=='v')
		isV = 1;
	char line[strlen(l)+1];
	memset(line,0,strlen(l)+1);
	sprintf(line,"%s",l);
	char * s = strtok(line,"\t");
	int i = 0;
	char * str = NULL;
	int x;
	int y;
	int w=0;
	int h=0;
	int size;
	int color=0;
	MyFont * myfont = NULL;
	//MyFont * font2 = NULL;
	while (s!= NULL) {
		switch(i)
		{
			case 1:
				str = s;
				break;
			case 2:
				x = atoi(s);
				break;
			case 3:
				y = atoi(s);
				break;
			case 4:
				w = atoi(s);
				break;
			case 5:
				h = atoi(s);
				break;
			case 6:
				color = atoi(s);
				break;
			case 7://font
#ifdef __DEBUG__
				if(strcmp(str,"㪟")==0 || strcmp(str,"敦")==0){
					str = "㪟";
					str = "敦";
					//s = "DroidSansFallback";
					//s = "HYQiHei-EZS,Light";
					//s = "HwChinese-Medium";
				}else if(strcmp(str,"㓂")==0){
					str = "寇";
				}
				//s = "Reeji-CloudLiShu-GBK-Regular";
				//s = "CloudSongDaGBK";
				//s = "MicrosoftYaHei";
				//s = "STXingkai_GBK";
				//s = "FZKTK--GBK1-0";
				//s = "DroidSansFallback";
				//s = "HYQiHei-EZS,Light";//"DroidSansChinese";
				//s = "FreeSerif";//"DroidSansChinese";
#endif
				if('0'<=*s && *s<='9')
					s = fonts[atoi(s)];
				myfont = getFontByName(s);
				if(myfont==NULL)
					myfont = getDefaultFont();
				if(strcmp(str,"秊")==0){
					myfont = getDefaultFont();
				}
				break;
			case 8:
				size = atoi(s);
				break;
			case 9://font2
				//if('0'<=*s && *s<='9') s = fonts[atoi(s)];
				//font2 = getFontByName(s);
				break;
		}
		++i;
		s = strtok(NULL, "\t");
	}

	if(str!=NULL)
	{
#ifdef __HAS_FREETYPE__
		//if(font2) myfont = font2;
#endif
		if(
				(unsigned char)*str<= 0x7f
		  ){
			myfont = getDefaultFont();
		}
		if(w<size)
			w=size;
		if(h<size)
			h=size;
		int deltax = 0;
		int deltay = 0;
		deltax = deltay = HPDF_Page_GetHeight(page)/841*2;
		if(!isV && strlen(str)==1)
		{
			switch(*str)
			{
				case 'j':
				case 'i':
					deltax-=size/8;
					break;
				case 'l':
					deltax-=size/8;
					break;
			}
		}
		draw_text(page,myfont,str,x+deltax,y+deltay,w,h,size,color,isV);
	}
}
void draw_graphics(HPDF_Page page,int x,int y,float scale,int lineSize,int lineColor,int fillColor,char * fill,char * cmds,char * coords)
{
	//int pageW = HPDF_Page_GetWidth(page);
	int pageH = HPDF_Page_GetHeight(page);
	HPDF_Page_SetLineWidth (page, lineSize);
	float r = (float)((lineColor>>16)&0xff)/0xff;
	float g = (float)((lineColor>>8)&0xff)/0xff;
	float b = (float)((lineColor)&0xff)/0xff;
	HPDF_Page_SetRGBStroke (page, r, g, b);
	if(strcmp(fill,"true")==0)
	{
		//printf("---------------------fill\n");
		float r = (float)((fillColor>>16)&0xff)/0xff;
		float g = (float)((fillColor>>8)&0xff)/0xff;
		float b = (float)((fillColor)&0xff)/0xff;
		HPDF_Page_SetRGBFill(page,r,g,b);
		//HPDF_Page_Fill(page);
	}
	int len = strlen(cmds);
	int i = 0;
	char * s = strtok(coords," ");
	while(i<len)
	{
		char cmd = (char)cmds[i];
		char * s2 = s;
		char * s3 = strtok(NULL, " ");
		int _x = (atof(s2)*scale+x);
		int _y = (atof(s3)*scale+y);
		switch(cmd)
		{
			case '1':
				//printf("moveTo\n");
				HPDF_Page_MoveTo(page,_x,pageH-_y);
				break;
			case '2':
				//printf("lineTo\n");
				HPDF_Page_LineTo(page,_x,pageH-_y);
				break;
		}
		s = strtok(NULL, " ");
		i+=2;
	}
	if(strcmp(fill,"true")==0){
		//HPDF_Page_ClosePath(page);
		//HPDF_Page_EndPath(page);
		HPDF_Page_ClosePathFillStroke(page);
		//HPDF_Page_FillStroke(page);
		//HPDF_Page_Fill(page);
		//HPDF_Page_ClosePathStroke(page);
		HPDF_Page_Rectangle (page, 0, 0, 0, 0);
	}

	HPDF_Page_Stroke (page);
}
void parsePic(HPDF_Page page,char * l)
{
	if(l==NULL || strlen(l)<10)
		return;
	char line[strlen(l)+1];
	memset(line,0,strlen(l)+1);
	sprintf(line,"%s",l);
	char * s = strtok(line,"\t");
	int i = 0;
	char * type = s;
	//printf("type: %s\n",s);
	int x;
	int y;
	int w=0;
	int h=0;
	char * url = NULL;
	float scale = 1.0;
	char * cmds = NULL;
	char * coords = NULL;
	int lineSize=0;
	int lineColor;
	int fillColor;
	char * fill;
	while (s!= NULL) {
		switch(i)
		{
			case 1:
				x = atoi(s);
				break;
			case 2:
				y = atoi(s);
				break;
			case 3:
				w = atoi(s);
				break;
			case 4:
				h = atoi(s);
				break;
			case 5:
				if(strcmp(type,"p")==0){
					url = s;
					//printf("%s\n",url);
				}else{
					scale = atof(s);
					//printf("Scale: %s\n",s);
				}
				break;
			case 6:
				lineSize = atoi(s);
				//printf("lineSize: %s\n",s);
				break;
			case 7:
				lineColor = atoi(s);
				//printf("lineColor: %s\n",s);
				break;
			case 8:
				fillColor = atoi(s);
				//printf("fillColor: %s\n",s);
				break;
			case 9:
				fill = s;
				//printf("fill: %s\n",s);
				break;
			case 10:
				cmds = s;
				//printf("cmds: %s\n",s);
				break;
			case 11:
				coords = s;
				//printf("coords: %s\n",s);
				break;
			default:
				//printf("Other: %s\n",s);
				break;
		}
		++i;
		s = strtok(NULL, "\t");
	}

	if(url!=NULL){
		draw_image_file(page,url,x,y,w,h);
	}else if(cmds){
		draw_graphics(page,x,y,scale,lineSize,lineColor,fillColor,fill,cmds,coords);
	}
}

HPDF_Page parseSize(char * l)
{
	if(l==NULL || strlen(l)<5)
		return NULL;
	char line[strlen(l)+1];
	memset(line,0,strlen(l)+1);
	sprintf(line,"%s",l);
	char * s = strtok(line,"\t");
	int i = 0;
	int w=0;
	int h=0;
	float scale = 1.0;
	char * url = NULL;
	while (s!= NULL) {
		switch(i)
		{
			case 1:
				w = atoi(s);
				break;
			case 2:
				h = atoi(s);
				break;
			case 3:
				scale = atof(s);
				break;
			case 4:
				url = s;
				break;
		}
		++i;
		s = strtok(NULL, "\t");
	}
	HPDF_Page page = HPDF_AddPage(pdf);
	if(url)
	{
		printf("bg: %s\n",url);
		HPDF_Image hpdfImage = HPDF_LoadJpegImageFromFile(pdf, url);
		if (hpdfImage){
			unsigned int _w = HPDF_Image_GetWidth(hpdfImage);
			unsigned int _h = HPDF_Image_GetHeight(hpdfImage);
			w =_w*scale;
			h =_h*scale;
		}
		HPDF_Page_SetHeight (page, h);
		HPDF_Page_SetWidth (page, w);
		draw_image(page, hpdfImage, 0, 0, w, h);
	}else{
		HPDF_Page_SetHeight(page, h);
		HPDF_Page_SetWidth (page, w);
	}
	//printf("size: %dx%d\n",w,h);
	return page;
}
void addPage(char * txtPath)
{
	int exists = fileExists(txtPath);
	//printf("\n%s,%d\n",txtPath,exists);
	if(!exists)
		return;
	printf("%s\n",txtPath);
	size_t l;
	char * s = readfile(txtPath,&l);
	//printf("%s\r\n",s);
	char * arr[strlen(s)];
	memset(arr,0,sizeof(arr));
	int i=0;
	char * line = strtok(s, "\n");
	while (line!= NULL){
		arr[i++]= line;
		//printf("%s\r\n",line);fflush(stdout);
		line = strtok(NULL, "\n");
	}
	//printf("numLines: %d\n",i);
	if(i==0)
		return;

	HPDF_Page page = NULL;
	int j=0;
	while(j<i)
	{
		char * line = arr[j];
		switch(*line)
		{
			case 't':
				if(page)
					parseTxt(page,line);
				break;
			case 's'://size and scale
				page = parseSize(line);
				break;
			case 'p':
			case 'g':
				if(page)
					parsePic(page,line);
			default:
				break;
		}
		++j;
	}
}

void saveToFile(char *filename,char * data,int datalen)
{
	FILE * file = fopen(filename,"w+");	
	fwrite(data,1,datalen,file);
	fclose(file);
}

int main(int nArgc, char** argv)
{
	//printf("\r\n%d",clock());fflush(stdout);

	pdf = HPDF_New (error_handler, NULL);
	if (!pdf) {
		printf ("error: cannot create PdfDoc object\n");
		return 1;
	}

	if (setjmp(env)) {
		HPDF_Free (pdf);
		return 1;
	}


	HPDF_SetInfoAttr (pdf, HPDF_INFO_PRODUCER,"db0@qq.com");
	//HPDF_SetInfoAttr (pdf, HPDF_INFO_AUTHOR ,"db0@qq.com");
	//HPDF_SetInfoAttr (pdf, HPDF_INFO_CREATOR,"db0@qq.com");
	//HPDF_SetInfoAttr (pdf, HPDF_INFO_TITLE,"db0@qq.com");
	//HPDF_SetInfoAttr (pdf, HPDF_INFO_SUBJECT,"db0@qq.com");
	//HPDF_SetInfoAttr (pdf, HPDF_INFO_KEYWORDS,"db0@qq.com");

	HPDF_UseCNSFonts(pdf);  
	HPDF_UseCNTFonts(pdf);  
	HPDF_UseCNSEncodings(pdf);
	HPDF_UseCNTEncodings(pdf);
	/**
	  HPDF_COMP_NONE - No compression.
	  HPDF_COMP_TEXT - Compress the contents stream of the page.
	  HPDF_COMP_IMAGE - Compress the streams of the image objects.
	  HPDF_COMP_METADATA - Other stream datas (fonts, cmaps and so on) are compressed.
	  HPDF_COMP_ALL - All stream datas are compressed (HPDF_COMP_TEXT | HPDF_COMP_IMAGE | HPDF_COMP_METADATA).
	  */
	HPDF_SetCompressionMode(pdf,HPDF_COMP_ALL);
	embedFonts();

	HPDF_SetCurrentEncoder (pdf, "GBK-EUC-V");
	HPDF_SetCurrentEncoder (pdf, "GBK-EUC-H");
	//HPDF_SetCurrentEncoder (pdf, "GB18030-EUC-H");
	//HPDF_Encoder * encoder =  HPDF_GetCurrentEncoder (pdf);
	//printf("encoder: %s\r\n",encoder);
	HPDF_STATUS status;
	status = HPDF_UseUTFEncodings(pdf);
	if(status==HPDF_OK)
	{
		//printf("\r\nHPDF_UseUTFEncodings\r\n");
	}
	//encoder =  HPDF_GetCurrentEncoder (pdf);
	//printf("encoder: %s\r\n",encoder);
	char * pdfName = "/home/libiao/test.pdf";//保存文件名
	if(nArgc>1){
		pdfName = (char *)argv[1];
	}

	char * dir = "/home/libiao/.appdata/com.huaien.jiapu2/Local Store/11360632/w/";
	int startIndex = 0;// 从第 startIndex 开始
	int numFiles = 0;//总页数
	int argIndex = 2;
	while(nArgc>argIndex)
	{
		if(nArgc>argIndex)
		{
			dir = argv[argIndex++];
		}
		if(nArgc>argIndex)
		{
			startIndex = atoi(argv[argIndex++]);
		}
		if(nArgc>argIndex)
		{
			numFiles = atoi(argv[argIndex++]);
		}
		printf("dir: %s\n",dir);
		printf("startIndex: %d\n",startIndex);
		char ** fileList = getFilesInDirectory(dir,".txt",startIndex-1,&numFiles);
		printf("numPages: %d\n",numFiles);
		int i=0;
		while(i<numFiles)
		{
			char * path = fileList[i];
			//path = NULL;
			if(path==NULL)
			{
				int pathLen = strlen(dir)+10;
				path = malloc(pathLen);
				memset(path,0,pathLen);
				sprintf(path,"%s/%d.txt",dir,i);
			}
			//printf("file: %s\n",path);
			addPage(path);
			++i;
		}
		free(fileList);
	}
	printf("-----------------------------%s\r\n",argv[1]);

	printf("saveToFile: %s\n",pdfName);
	if(1){
		HPDF_SaveToFile (pdf, pdfName);   
	}else{
		//HPDF_SaveToStream(pdf);
		//int streamSize = HPDF_GetStreamSize(pdf); 
		//char * data = malloc(streamSize);
		//HPDF_ReadFromStream(pdf,data,&streamSize);
		//saveToFile(pdfName,data,streamSize);
		//free(data);
	}


	printf("your pdf already ok\n");
	HPDF_Free (pdf);

	//printf("\r\n%d",CLOCKS_PER_SEC);fflush(stdout);
	//printf("\r\n%d",clock());fflush(stdout);
	return 0;
}

